
#include "SniffDump.hpp"


SniffDump::SniffDump(const SniffDump &Other) : Handle(NULL), DataLink(0) {
}

SniffDump::~SniffDump() {
	if (Handle) pcap_close(Handle);
}

SniffDump& SniffDump::operator=(const SniffDump &Other) {
	return *this;
}

SniffDump::SniffDump(const std::string &Filename) : Handle(NULL), DataLink(0) {
	char ErrBuf[PCAP_ERRBUF_SIZE];
	Handle = pcap_open_offline(Filename.c_str(), ErrBuf);
	if (!Handle) {
		std::cerr << "Cannot open dump " << Filename << ": " << ErrBuf << std::endl;
		return;
	}
	DataLink = pcap_datalink(Handle);
	if (DataLink == DLT_EN10MB) {
		std::cerr << "10/100/1000 MBit Ethernet link layer" << std::endl;
#ifdef DLT_IEEE802_11_RADIO
	} else if (DataLink == DLT_IEEE802_11_RADIO) {
		std::cerr << "IEEE 802.11 + BSD Radiotap header" << std::endl;
#endif
	} else {
		std::cerr << "Unknown link layer " << DataLink << std::endl;
	}
}

bool SniffDump::Next(Packet &ResultPacket) {
	struct pcap_pkthdr Header;
	const u_char *PktData;
	if (!Handle) return false;
	PktData = pcap_next(Handle, &Header);
	if (Header.len != Header.caplen) {
		std::cerr << "Truncated packet captured (len = " << Header.len << ", but caplen = " << Header.caplen <<"), aborting.";
		return false;
	}
	ResultPacket.Set(PktData, Header.len);
	return PktData;
}

